package com.hugh.common.data;

import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.Temporal;

/**
 * @Author: Hugh
 * @Date: 2020/5/25
 */
public class LocalDateTimeUtils extends DateHandler {
    /**
     * 默认时区
     */
    private static final String DEFAULT_ZONE = "Asia/Shanghai";
    /**
     * 默认的开始时间
     */
    public static final LocalDateTime START_TIME = LocalDateTime.of(2000, 1, 1, 0, 0, 0);

    /**
     * long值转换为LocalDateTime对象
     *
     * @param time
     * @return
     */
    public static LocalDateTime of(Long time) {

        return LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.of(DEFAULT_ZONE));
    }

    /**
     * 以指定格式生成字符串
     *
     * @param time    毫秒数
     * @param pattern 格式
     * @return
     */
    public static String format(Long time, String pattern) {
        LocalDateTime localDateTime = of(time);
        return format(localDateTime, pattern);
    }


    /**
     * 以指定格式生成字符串,
     *
     * @param second  秒数
     * @param pattern 格式
     * @return
     */
    public static String format(Integer second, String pattern) {
        return format(Long.valueOf(second) * 1000, pattern);
    }

    /**
     * 以默认格式yyyy-MM-dd格式生成字符串
     *
     * @param second 秒数
     * @return
     */
    public static String format(Integer second) {
        return format(second, DATE_PATTERN);
    }

    /**
     * 转换字符串日期格式为LocalDateTime
     *
     * @param dateStr
     * @param pattern
     * @return LocalDateTime
     */
    public static LocalDateTime parseDate(String dateStr, String pattern) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        if (StringUtils.isEmpty(pattern)) {
            pattern = DATE_TIME_PATTERN;
        }

        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        try {
            return LocalDateTime.parse(dateStr, df);
        } catch (DateTimeParseException e) {

            LocalDate localDate = LocalDate.parse(dateStr, df);
            return LocalDateTime.of(localDate, LocalTime.MIN);
        } catch (Exception e) {
//            log.error("formatDate error:", e);
        }
        return null;
    }

    /**
     * 以yyyy-MM-dd HH:mm:SS.SSS格式生成字符串
     *
     * @param time
     * @return
     */
    public static String format(Long time) {
        LocalDateTime localDateTime = of(time);
        return format(localDateTime);
    }

    /**
     * 以yyyy-MM-dd HH:mm:ss.SSS的格式
     *
     * @param localDateTime
     * @return
     */
    public static String format(LocalDateTime localDateTime) {
        return format(localDateTime, DATE_TIME_MILL_PATTERN);
    }

    /**
     * 以传入的时间格式格式化时间
     *
     * @param localDateTime
     * @param pattern
     * @return
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        if (null != localDateTime) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
            return localDateTime.format(formatter);
        } else {
            return null;
        }
    }

    /**
     * 获取某天的0点
     *
     * @param date
     * @return
     */
    public static LocalDateTime startOfDay(LocalDateTime date) {
        return date.with(LocalTime.MIN);
    }

    /**
     * 获取今天的0点
     *
     * @return
     */
    public static LocalDateTime startOfToday() {
        return startOfDay(LocalDateTime.now());
    }

    /**
     * 获取时间戳
     *
     * @param dateTime
     * @return
     */
    public static long getLong(LocalDateTime dateTime) {
        if (null == dateTime) {
            return 0L;
        } else {
            return Timestamp.valueOf(dateTime).getTime();
        }
    }

    /**
     * 获取时间戳
     *
     * @param localDate
     * @return
     */
    public static long getLong(LocalDate localDate) {
        if (null == localDate) {
            return 0L;
        } else {
            return getLong(LocalDateTime.of(localDate, LocalTime.MIN));
        }
    }

    /**
     * 由字符串的时间获取最小毫秒数
     *
     * @param time    时间字符串
     * @param pattern 格式
     * @return
     */
    public static Long getMillionSecond(String time, String pattern) {
        LocalDateTime localDateTime = parseDate(time, pattern);
        return getLong(localDateTime);
    }

    /**
     * 由字符串
     *
     * @param time
     * @param pattern
     * @return
     */
    public static Long getSecond(String time, String pattern) {
        return getMillionSecond(time, pattern) / 1000;
    }

    /**
     * 获取UNIX时间戳
     *
     * @param dateTime
     * @return
     */
    public static int getUnixStamp(LocalDateTime dateTime) {
        return Math.abs((int) (getLong(dateTime) / 1000));
    }

    /**
     * 修正pattern
     *
     * @param time          时间字符串
     * @param pattern       目前的pattern
     * @param targetPattern 目标pattern
     * @return
     */
    public static String fixPattern(String time, String pattern, String targetPattern) {
        LocalDateTime localDateTime = parseDate(time, pattern);
        return format(localDateTime, targetPattern);
    }

    /**
     * 修正pattern
     * 默认来源pattern为yyyy-MM-dd hh:mm:ss
     *
     * @param time          时间字符串
     * @param targetPattern 目前pattern
     * @return
     */
    public static String fixPattern(String time, String targetPattern) {
        return fixPattern(time, DATE_TIME_PATTERN, targetPattern);
    }

    public static String duration(Temporal startTime, Temporal endTime) {
        if (null == startTime || null == endTime){
            return "0分";
        }
        Duration duration = Duration.between(startTime, endTime);
        long minutes = duration.toMinutes();
        long hours = minutes / 60;
        minutes = minutes % 60;
        if (0 != hours){
            return String.format("%d时%d分", hours, minutes);
        }else {
            return String.format("%d分",minutes);
        }
    }
}
